package com.ruoyi.material.service.impl;

import java.util.*;

import com.ruoyi.base.util.GenCodeUtils;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.material.domain.ReceiptMaterialInfo;
import com.ruoyi.material.domain.WarehouseInfo;
import com.ruoyi.material.mapper.MaterialInfoMapper;
import com.ruoyi.material.mapper.ReceiptMaterialInfoMapper;
import com.ruoyi.material.mapper.WarehouseInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.stream.Collectors;

import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.material.domain.MaterialInfo;
import com.ruoyi.material.mapper.OutboundOrderMapper;
import com.ruoyi.material.domain.OutboundOrder;
import com.ruoyi.material.service.IOutboundOrderService;

/**
 * 出库Service业务层处理
 * 
 * @author ruoyi
 * @date 2022-08-25
 */
@Service
public class OutboundOrderServiceImpl implements IOutboundOrderService 
{
    @Autowired
    private OutboundOrderMapper outboundOrderMapper;
    @Autowired
    private MaterialInfoMapper materialInfoMapper;

    @Autowired
    private ReceiptMaterialInfoMapper receiptMaterialInfoMapper;

    @Autowired
    private WarehouseInfoMapper warehouseInfoMapper;
    /**
     * 查询出库
     * 
     * @param id 出库主键
     * @return 出库
     */
    @Override
    public OutboundOrder selectOutboundOrderById(Long id)
    {
        OutboundOrder outboundOrder = outboundOrderMapper.selectOutboundOrderById(id);
        List<String> list=new ArrayList<>();
        list.add(outboundOrder.getOutboundNo());
        List<MaterialInfo> materialInfos = materialInfoMapper.selectMaterialInfoByReceiptMaterialNos(list);
        //todo
        for (MaterialInfo m:materialInfos){
            m.setRemainderCount(materialInfoMapper.selectreMainderCount(m.getMaterialNo(),m.getProjectNo()));
        }
        outboundOrder.setMaterialInfoList(materialInfos);
        return outboundOrder;
    }

    /**
     * 查询出库列表
     * 
     * @param outboundOrder 出库
     * @return 出库
     */
    @Override
    public List<OutboundOrder> selectOutboundOrderList(OutboundOrder outboundOrder)
    {
        List<OutboundOrder> list = outboundOrderMapper.selectOutboundOrderList(outboundOrder);
        List<String> collect = list.stream().map(OutboundOrder::getOutboundNo).collect(Collectors.toList());

        if (!StringUtils.isNull(collect) && collect.size()>0){
            List<MaterialInfo> materialInfoList= materialInfoMapper.selectMaterialInfoByReceiptMaterialNos(collect);
            Map<String, List<MaterialInfo>> map = materialInfoList.stream().collect(Collectors.groupingBy(MaterialInfo::getReceiptMaterialNo));
            for (OutboundOrder out:list)
                out.setMaterialInfoList(map.get(out.getOutboundNo()));
        }
        return list;
    }

    /**
     * 新增出库
     * 
     * @param outboundOrder 出库
     * @return 结果
     */
    @Transactional
    @Override
    public int insertOutboundOrder(OutboundOrder outboundOrder)
    {
        outboundOrder.setCreateTime(DateUtils.getNowDate());
        SysUser user = SecurityUtils.getLoginUser().getUser();
        outboundOrder.setCreateBy(user.getUserName());
        outboundOrder.setOutboundNo(GenCodeUtils.getOutBoundOrderNo());

        int rows = outboundOrderMapper.insertOutboundOrder(outboundOrder);
        insertMaterialInfo(outboundOrder);
        return rows;
    }

    /**
     * 修改出库
     * 
     * @param outboundOrder 出库
     * @return 结果
     */
    @Transactional
    @Override
    public int updateOutboundOrder(OutboundOrder outboundOrder)
    {
        OutboundOrder i = outboundOrderMapper.selectOutboundOrderById(outboundOrder.getId());

        if("1".equals(i.getStatus())){
            throw new ServiceException("当前出库单已完成出库，无法修改!");
        }
        outboundOrderMapper.deleteMaterialInfoByReceiptMaterialNo(outboundOrder.getOutboundNo());
        insertMaterialInfo(outboundOrder);
        SysUser user = SecurityUtils.getLoginUser().getUser();

        outboundOrder.setUpdateBy(user.getUserName());
                outboundOrder.setUpdateTime(new Date());
        return outboundOrderMapper.updateOutboundOrder(outboundOrder);
    }

    /**
     * 批量删除出库
     * 
     * @param ids 需要删除的出库主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteOutboundOrderByIds(Long[] ids)
    {

        outboundOrderMapper.deleteMaterialInfoByReceiptMaterialNos(ids);

        return outboundOrderMapper.deleteOutboundOrderByIds(ids);
    }

    /**
     * 删除出库信息
     * 
     * @param id 出库主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteOutboundOrderById(Long id)
    {
        OutboundOrder outboundOrder = outboundOrderMapper.selectOutboundOrderById(id);
        if (StringUtils.isNotNull(outboundOrder)){
            outboundOrderMapper.deleteMaterialInfoByReceiptMaterialNo(outboundOrder.getOutboundNo());
        }

        return outboundOrderMapper.deleteOutboundOrderById(id);
    }

    @Override
    public int deleteOutboundOrderByOutboundNo(Long[] outboundNo) {
        List<OutboundOrder>list= outboundOrderMapper.selectOutboundOrderOutboundNo(outboundNo);
        List<String> collect = list.stream().map(OutboundOrder::getOutboundNo).collect(Collectors.toList());

        outboundOrderMapper.deleteMaterialInfoByOutboundNo( collect.stream().toArray(String[]::new));
        return outboundOrderMapper.deleteOutboundOrderByOrderByIds(collect.stream().toArray(String[]::new));
    }

    @Override
    public AjaxResult changeStatus(Long id) {
        //查询出库单
        OutboundOrder outboundOrder = outboundOrderMapper.selectOutboundOrderById(id);
        if("1".equals(outboundOrder.getStatus())){
            return AjaxResult.error("当前出库单已完成出库，无法再次出库!");
        }

        List<String> list=new ArrayList<>();
        list.add(outboundOrder.getOutboundNo());
        List<MaterialInfo> materialInfoList = materialInfoMapper.selectMaterialInfoByReceiptMaterialNos(list);

        Map<Long,Long> map=new HashMap<>();
        for (MaterialInfo materialInfo : materialInfoList) {
            //查询库存，确定物料是否存在
            WarehouseInfo warehouseInfo=warehouseInfoMapper.selectWarehouseInfoByChecks(materialInfo);
            if (StringUtils.isNotNull(warehouseInfo)){
                long l = warehouseInfo.getRemainderCount() - materialInfo.getCount();
                if (l<0){
                    throw new ServiceException(materialInfo.getMaterialName()+"库存数量小于出库数量");
                }
                map.put(warehouseInfo.getId(),l);
            }else{
                throw new ServiceException("要出库的 "+materialInfo.getMaterialName()+" 不存在");
            }
        }
        for (Long newId:map.keySet()){
            warehouseInfoMapper.updateCheckout(newId,map.get(newId));
        }
        //更新入料单
        outboundOrderMapper.updateOutboundOrderStatus(outboundOrder.getId());
        return AjaxResult.success();
    }

    /**
     * 新增物料信息信息
     * 
     * @param outboundOrder 出库对象
     */
    public void insertMaterialInfo(OutboundOrder outboundOrder)
    {
        List<MaterialInfo> materialInfoList = outboundOrder.getMaterialInfoList();//获取出料的信息
        String id = outboundOrder.getOutboundNo();//出库单id
        if (StringUtils.isNotNull(materialInfoList))
        {
            List<MaterialInfo> list = new ArrayList<MaterialInfo>();
            for (MaterialInfo materialInfo : materialInfoList)
            {
                materialInfo.setReceiptMaterialNo(id);
                list.add(materialInfo);
            }
            if (list.size() > 0)
            {
                outboundOrderMapper.batchMaterialInfo(list);
            }
        }
    }


}
